package com.siyoumi.app.modules.app_book.service.handle_order;

import com.siyoumi.app.entity.BookOrder;
import com.siyoumi.app.entity.BookSku;
import com.siyoumi.app.entity.BookStore;
import com.siyoumi.app.modules.app_book.service.BookOrderHandleAbs;
import com.siyoumi.app.modules.app_book.service.SvcBookSet;
import com.siyoumi.app.modules.app_book.service.SvcBookSku;
import com.siyoumi.app.modules.app_book.service.SvcBookStore;
import com.siyoumi.app.modules.app_book.vo.SkuDayData;
import com.siyoumi.component.LogPipeLine;
import com.siyoumi.component.XApp;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.service.IWebService;
import com.siyoumi.util.XReturn;
import com.siyoumi.validator.XValidator;

import java.math.BigDecimal;
import java.util.List;

/**
 * 计算订单金额
 */
public class BookOrderHandle80PriceTotal
        extends BookOrderHandleAbs
        implements IWebService {
    @Override
    public XReturn orderBeforeCheck() {
        return EnumSys.OK.getR();
    }

    @Override
    public String getTitle() {
        return "计算订单金额";
    }

    @Override
    public XReturn handle(BookOrder entityOrder) {
        LogPipeLine log = getLog();
        //BigDecimal priceSku = entityOrder.getBorder_sku_day_price().multiply(BigDecimal.valueOf(entityOrder.getBorder_sku_user_count())) //房间人数
        //        .multiply(BigDecimal.valueOf(entityOrder.getBorder_day_final())) //晚数
        //        ;
        BookSku entitySku = SvcBookSku.getApp().getEntity(entityOrder.getBorder_sku_id());
        List<SkuDayData> listDaySku = SvcBookSku.getBean().listDay(entitySku, entityOrder.getBorder_date_begin(), entityOrder.getBorder_date_end());
        BigDecimal priceSku; //基础价
        BigDecimal priceSkuAdd; //加价
        Integer userCount; //按人数计算房费价格（不能超房间人数）
        if (entityOrder.getBorder_set_user_count() < entityOrder.getBorder_sku_user_count()) { //入住人数小于房间人数，启用包房价
            priceSku = listDaySku.stream()
                    .map(item -> item.getDay_price_private())
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            priceSkuAdd = listDaySku.stream()
                    .map(item -> item.getDay_price_private_add())
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            userCount = entityOrder.getBorder_set_user_count();
        } else { //拼房价
            priceSku = listDaySku.stream()
                    .map(item -> item.getDay_price())
                    .reduce(BigDecimal.ZERO, BigDecimal::add); //加价金额

            priceSkuAdd = listDaySku.stream()
                    .map(item -> item.getDay_price_add())
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            if (priceSku.compareTo(BigDecimal.ZERO) <= 0) {
                XValidator.err(20058, "房间未配置包房价");
            }
            userCount = entityOrder.getBorder_sku_user_count();
        }
        log.setLogMsgFormat("房间人数：{0}，入住人数：{1}，计算房费人数：{2}"
                , entityOrder.getBorder_sku_user_count().toString()
                , entityOrder.getBorder_set_user_count().toString()
                , userCount.toString()
        );
        //sku基础总金额
        BigDecimal priceSkuTotal = priceSku
                .multiply(BigDecimal.valueOf(userCount)) //人数
                .multiply(BigDecimal.valueOf(entityOrder.getBorder_spu_count())); //房间数
        priceSkuTotal = XApp.toDecimalPay(priceSkuTotal);
        log.setLogMsgFormat("房间基础总金额：{0} = {1} * {2}，天数：{3}"
                , priceSkuTotal.toString()
                , priceSku.toString()
                , entityOrder.getBorder_spu_count().toString()
                , entityOrder.getBorder_day_final().toString()
        );
        entityOrder.setBorder_price_sku(priceSkuTotal);

        //sku加价总金额
        BigDecimal priceSkuAddTotal = priceSkuAdd
                .multiply(BigDecimal.valueOf(userCount)) //人数
                .multiply(BigDecimal.valueOf(entityOrder.getBorder_spu_count())); //房间数

        BigDecimal priceSpuAppendDay = getListDay().stream()
                .filter(item -> item.getAdd_price().compareTo(BigDecimal.ZERO) > 0)
                .map(item -> item.getAdd_price())
                .reduce(BigDecimal.ZERO, BigDecimal::add); //加价金额
        BigDecimal priceSpuAppendTotal = priceSpuAppendDay
                .multiply(BigDecimal.valueOf(entityOrder.getBorder_spu_count()))//房间数
                ;
        priceSpuAppendTotal = XApp.toDecimalPay(priceSpuAppendTotal);
        log.setLogMsgFormat("房间加价总金额：{0} + {4} = {1} * {2}，天数：{3}"
                , priceSkuAddTotal.toString()
                , priceSkuAdd.toString()
                , entityOrder.getBorder_spu_count().toString()
                , entityOrder.getBorder_day_final().toString()
                , priceSpuAppendTotal.toString()
        );
        entityOrder.setBorder_price_sku_append_sku(priceSkuAddTotal);
        entityOrder.setBorder_price_sku_append_spu(priceSpuAppendTotal);
        entityOrder.setBorder_price_sku_append(entityOrder.getBorder_price_sku_append_sku().add(entityOrder.getBorder_price_sku_append_spu()));

        BigDecimal priceSet = entityOrder.getBorder_set_day_price()
                .multiply(BigDecimal.valueOf(entityOrder.getBorder_set_user_count())) //套餐人数
                .multiply(BigDecimal.valueOf(entityOrder.getBorder_day_final())) //晚数
                ;
        priceSet = XApp.toDecimalPay(priceSet);
        log.setLogMsgFormat("套餐基础总金额：{0} = {3} * {1} * {2}"
                , priceSet.toString()
                , entityOrder.getBorder_set_user_count().toString()
                , entityOrder.getBorder_day_final().toString()
                , entityOrder.getBorder_set_day_price().toString()
        );
        entityOrder.setBorder_price_set(priceSet);

        BigDecimal priceSetAppendDay = SvcBookSet.getBean().dayPriceTotal(entityOrder.getBorder_set_id(), entityOrder.getBorder_date_begin(), entityOrder.getBorder_date_end_final());
        BigDecimal priceSetAppendTotal = priceSetAppendDay
                .multiply(BigDecimal.valueOf(entityOrder.getBorder_set_user_count())) //套餐人数
                //.multiply(BigDecimal.valueOf(entityOrder.getBorder_spu_count()))//房间数
                ;
        priceSetAppendTotal = XApp.toDecimalPay(priceSetAppendTotal);
        entityOrder.setBorder_price_set_append(priceSetAppendTotal);
        log.setLogMsgFormat("套餐加价总金额：{0}", priceSetAppendTotal.toString());
        //原订单金额
        entityOrder.setBorder_price_original(entityOrder.matchOriginalPrice());
        //房费金额
        entityOrder.setBorder_price_spu(entityOrder.matchSpuPrice());
        //分销金额
        entityOrder.setBorder_price_share_final(entityOrder.matchSharePrice());
        entityOrder.setBorder_price_pay(entityOrder.getBorder_price_final()); //支付金额
        if (entityOrder.getBorder_edit() == 0) {
            //押金计算
            BigDecimal depositPrice = BigDecimal.ZERO;
            if (getVo().getPay_deposit() > 0) {
                //开启订金支付
                BookStore entityStore = SvcBookStore.getApp().getEntity(entityOrder.getBorder_store_id());
                if (entityStore.getBstore_deposit_enable() == 1) { //按比例
                    depositPrice = entityOrder.getBorder_price_original().multiply(XApp.decimal100(entityStore.getBstore_deposit_rate()));
                }
                if (entityStore.getBstore_deposit_enable() == 2) { //固定金额
                    depositPrice = entityStore.getBstore_deposit_rate();
                }
                depositPrice = XApp.toDecimalPay(depositPrice);
                entityOrder.setBorder_price_pay(depositPrice); //押金支付
            } else {
                entityOrder.setBorder_price_pay(entityOrder.getBorder_price_spu()); //全款支付
            }
            entityOrder.setBorder_deposit_price(depositPrice);
            log.setLogMsgFormat("支付金额：{0}", entityOrder.getBorder_price_pay().toString());
        }
        entityOrder.setBorder_price_pay01(BigDecimal.ZERO);
        entityOrder.setBorder_price_final(entityOrder.matchFinalPrice());
        log.setLogMsgFormat("房费：{0}", entityOrder.getBorder_price_spu().toString());
        log.setLogMsgFormat("最终订单金额 {0} = 押金：{1} + 房费：{2}"
                , entityOrder.getBorder_price_final().toString()
                , entityOrder.getBorder_deposit_price().toString()
                , entityOrder.getBorder_price_spu().toString()
        );

        return EnumSys.OK.getR();
    }
}

